'use client';

import React, { forwardRef, useState, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { cn, getImageFromPaste } from '@/utils';
import { PhotoIcon, XMarkIcon } from '@heroicons/react/24/outline';

export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label?: string;
  error?: string;
  success?: string;
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
  variant?: 'default' | 'filled' | 'underlined';
}

export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
  label?: string;
  error?: string;
  success?: string;
  variant?: 'default' | 'filled';
  supportImages?: boolean;
  images?: string[];
  onImagesChange?: (images: string[]) => void;
  maxImages?: number;
}

const Input = forwardRef<HTMLInputElement, InputProps>((
  {
    className,
    label,
    error,
    success,
    leftIcon,
    rightIcon,
    variant = 'default',
    ...props
  },
  ref
) => {
  const [focused, setFocused] = useState(false);
  
  const inputClasses = cn(
    // 基础样式
    'w-full transition-all duration-200 outline-none',
    'placeholder:text-gray-400',
    
    // 变体样式
    {
      // Default
      'px-4 py-3 rounded-xl border bg-white shadow-sm': variant === 'default',
      'border-gray-200 hover:border-gray-300 focus:border-blue-500 focus:ring-4 focus:ring-blue-500/10':
        variant === 'default' && !error && !success,
      
      // Filled
      'px-4 py-3 rounded-xl bg-gray-50 border border-transparent': variant === 'filled',
      'hover:bg-gray-100 focus:bg-white focus:border-blue-500 focus:ring-4 focus:ring-blue-500/10':
        variant === 'filled' && !error && !success,
      
      // Underlined
      'px-0 py-2 border-0 border-b-2 bg-transparent rounded-none': variant === 'underlined',
      'border-gray-200 hover:border-gray-300 focus:border-blue-500':
        variant === 'underlined' && !error && !success,
    },
    
    // 状态样式
    {
      'border-red-300 focus:border-red-500 focus:ring-red-500/10': error,
      'border-green-300 focus:border-green-500 focus:ring-green-500/10': success,
    },
    
    // 图标样式
    {
      'pl-11': leftIcon && variant !== 'underlined',
      'pr-11': rightIcon && variant !== 'underlined',
    },
    
    className
  );

  return (
    <div className="space-y-1">
      {label && (
        <motion.label
          className={cn(
            'block text-sm font-medium transition-colors duration-200',
            {
              'text-gray-700': !error && !success,
              'text-red-600': error,
              'text-green-600': success,
            }
          )}
          initial={{ opacity: 0.7 }}
          animate={{ opacity: focused ? 1 : 0.8 }}
        >
          {label}
        </motion.label>
      )}
      
      <div className="relative">
        {/* 左侧图标 */}
        {leftIcon && (
          <div className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400">
            {leftIcon}
          </div>
        )}
        
        {/* 输入框 */}
        <input
          ref={ref}
          className={inputClasses}
          onFocus={() => setFocused(true)}
          onBlur={() => setFocused(false)}
          {...props}
        />
        
        {/* 右侧图标 */}
        {rightIcon && (
          <div className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400">
            {rightIcon}
          </div>
        )}
      </div>
      
      {/* 错误或成功消息 */}
      <AnimatePresence mode="wait">
        {(error || success) && (
          <motion.div
            initial={{ opacity: 0, y: -10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -10 }}
            transition={{ duration: 0.2 }}
            className={cn(
              'text-xs font-medium',
              {
                'text-red-600': error,
                'text-green-600': success,
              }
            )}
          >
            {error || success}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
});

Input.displayName = 'Input';

const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>((
  {
    className,
    label,
    error,
    success,
    variant = 'default',
    supportImages = false,
    images = [],
    onImagesChange,
    maxImages = 5,
    ...props
  },
  ref
) => {
  const [focused, setFocused] = useState(false);
  const [isDragOver, setIsDragOver] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  
  const textareaClasses = cn(
    // 基础样式
    'w-full transition-all duration-200 outline-none resize-none',
    'placeholder:text-gray-400 leading-relaxed',
    
    // 变体样式
    {
      // Default
      'px-4 py-3 rounded-xl border bg-white shadow-sm': variant === 'default',
      'border-gray-200 hover:border-gray-300 focus:border-blue-500 focus:ring-4 focus:ring-blue-500/10':
        variant === 'default' && !error && !success && !isDragOver,
      
      // Filled
      'px-4 py-3 rounded-xl bg-gray-50 border border-transparent': variant === 'filled',
      'hover:bg-gray-100 focus:bg-white focus:border-blue-500 focus:ring-4 focus:ring-blue-500/10':
        variant === 'filled' && !error && !success && !isDragOver,
    },
    
    // 状态样式
    {
      'border-red-300 focus:border-red-500 focus:ring-red-500/10': error,
      'border-green-300 focus:border-green-500 focus:ring-green-500/10': success,
      'border-blue-400 ring-4 ring-blue-500/20': isDragOver,
    },
    
    className
  );

  const handlePaste = async (e: React.ClipboardEvent) => {
    if (!supportImages || !onImagesChange) return;
    
    const imageUrl = await getImageFromPaste(e);
    if (imageUrl && images.length < maxImages) {
      onImagesChange([...images, imageUrl]);
    }
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragOver(false);
    
    if (!supportImages || !onImagesChange) return;
    
    const files = Array.from(e.dataTransfer.files).filter(file => 
      file.type.startsWith('image/')
    );
    
    files.forEach(async (file) => {
      if (images.length < maxImages) {
        const { compressImage } = await import('@/utils');
        const imageUrl = await compressImage(file);
        onImagesChange([...images, imageUrl]);
      }
    });
  };

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragOver(true);
  };

  const handleDragLeave = () => {
    setIsDragOver(false);
  };

  const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(e.target.files || []);
    
    for (const file of files) {
      if (images.length >= maxImages) break;
      
      const { compressImage } = await import('@/utils');
      const imageUrl = await compressImage(file);
      onImagesChange?.([...images, imageUrl]);
    }
    
    // 清空文件输入
    e.target.value = '';
  };

  const removeImage = (index: number) => {
    const newImages = images.filter((_, i) => i !== index);
    onImagesChange?.(newImages);
  };

  return (
    <div className="space-y-3">
      {label && (
        <motion.label
          className={cn(
            'block text-sm font-medium transition-colors duration-200',
            {
              'text-gray-700': !error && !success,
              'text-red-600': error,
              'text-green-600': success,
            }
          )}
          initial={{ opacity: 0.7 }}
          animate={{ opacity: focused ? 1 : 0.8 }}
        >
          {label}
        </motion.label>
      )}
      
      <div className="relative">
        <textarea
          ref={ref}
          className={textareaClasses}
          onFocus={() => setFocused(true)}
          onBlur={() => setFocused(false)}
          onPaste={handlePaste}
          onDrop={handleDrop}
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
          rows={4}
          {...props}
        />
        
        {/* 图片支持提示 */}
        {supportImages && (
          <AnimatePresence>
            {(focused || isDragOver) && (
              <motion.div
                initial={{ opacity: 0, y: 10 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, y: 10 }}
                className="absolute bottom-3 right-3 flex items-center gap-2"
              >
                <button
                  type="button"
                  onClick={() => fileInputRef.current?.click()}
                  className="p-1.5 text-gray-400 hover:text-gray-600 transition-colors rounded-lg hover:bg-gray-100"
                >
                  <PhotoIcon className="w-4 h-4" />
                </button>
                <span className="text-xs text-gray-400">
                  支持粘贴/拖拽图片
                </span>
              </motion.div>
            )}
          </AnimatePresence>
        )}
      </div>
      
      {/* 隐藏的文件输入 */}
      {supportImages && (
        <input
          ref={fileInputRef}
          type="file"
          accept="image/*"
          multiple
          className="hidden"
          onChange={handleFileSelect}
        />
      )}
      
      {/* 图片预览 */}
      {supportImages && images.length > 0 && (
        <motion.div
          initial={{ opacity: 0, height: 0 }}
          animate={{ opacity: 1, height: 'auto' }}
          className="grid grid-cols-3 gap-2"
        >
          {images.map((image, index) => (
            <motion.div
              key={index}
              initial={{ opacity: 0, scale: 0.8 }}
              animate={{ opacity: 1, scale: 1 }}
              className="relative group aspect-square rounded-lg overflow-hidden bg-gray-100"
            >
              <img
                src={image}
                alt={`上传的图片 ${index + 1}`}
                className="w-full h-full object-cover"
              />
              <motion.button
                initial={{ opacity: 0 }}
                whileHover={{ opacity: 1 }}
                onClick={() => removeImage(index)}
                className="absolute top-1 right-1 p-1 bg-red-500 text-white rounded-full shadow-sm"
              >
                <XMarkIcon className="w-3 h-3" />
              </motion.button>
            </motion.div>
          ))}
        </motion.div>
      )}
      
      {/* 错误或成功消息 */}
      <AnimatePresence mode="wait">
        {(error || success) && (
          <motion.div
            initial={{ opacity: 0, y: -10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -10 }}
            transition={{ duration: 0.2 }}
            className={cn(
              'text-xs font-medium',
              {
                'text-red-600': error,
                'text-green-600': success,
              }
            )}
          >
            {error || success}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
});

Textarea.displayName = 'Textarea';

export { Input, Textarea };